package fr.skolian.core.data
{
	import flash.events.EventDispatcher;
	import flash.utils.describeType;
	import flash.utils.getDefinitionByName;
	
	import fr.skolian.core.interfaces.IData;
	
	
/*Skolian - Content management system for primary school - Copyright (c) 2011 - Olivier Gianotti - This file is part of Skolian. Skolian is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Skolian is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Skolian.  If not, see <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 

Skolian - Application de gestion de contenus pédagogiques en école primaire. Copyright (C) 2011 - Olivier Gianotti - Ce fichier est une partie de Skolian. Skolian est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier au titre des clauses de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre discrétion) une version ultérieure quelconque. Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même une garantie implicite de COMMERCIABILITE ou DE CONFORMITE A UNE UTILISATION PARTICULIERE. Voir la Licence Publique Générale GNU pour plus de détails. Vous devriez avoir reçu un exemplaire de la Licence Publique Générale GNU avec ce programme ; si ce n'est pas le cas, consultez <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 
*/

public class AbstractData extends EventDispatcher implements IData
	{
		public function AbstractData()
		{
			super();
		}
		private function setVectorFromObject(vector:String,typeName:String,datas:Object):void{
			var type:Class = getDefinitionByName(typeName) as Class;
			for each( var data:Object in datas ){
				var item:IData = new type();
				item.populate(data);
				this[vector]["push"](item);
			}
			
		}
		
		public function populate(data:Object):IData{
			var description:XML = new XML(describeType(this));
			var accessors:XMLList = description..accessor;
			var reg:RegExp;
			for each( var accessor:XML in accessors ){
				switch(true){
					case !data.hasOwnProperty(accessor.@name) :
						//trace("not populated : "+accessor.@name,data[accessor.@name]);
						break;
					case String(accessor.@type).indexOf("__AS3__.vec::Vector") == 0 :
						if(!this[accessor.@name])this[accessor.@name] = new (getDefinitionByName(accessor.@type) as Class)();
						reg = /(<)+([a-zA-Z.:]*)+(>)/g;
						var typeName:String = String(reg.exec(accessor.@type)[0]);
						typeName = typeName.substr(1,typeName.length-2).split("::").join(".");
						this.setVectorFromObject(accessor.@name,typeName,data[accessor.@name]);
						break;
					case String(accessor.@type).indexOf(".")>0 :
						if(!this[accessor.@name])this[accessor.@name] = new (getDefinitionByName(accessor.@type) as Class)();
						if(this[accessor.@name] as IData){
							(this[accessor.@name] as IData).populate(data[accessor.@name]);
						}
						break;
					case accessor.@type == "Boolean" :  
					case accessor.@type == "String" :					
					case accessor.@type == "Number" || accessor.@type == "int"|| accessor.@type == "uint" :
					case accessor.@type == "Object" :
					case accessor.@type == "Array" :
					case accessor.@type == "Dictionary" :
					default:
						this[accessor.@name] = data[accessor.@name];
						break;
				}
			}
			afterPopulate();
			return this;
		}
		
		protected function afterPopulate():void{
			
		}
		
		public function clear():void{
		}
		
	}
}